import React, { useCallback, useEffect, forwardRef, useImperativeHandle, useRef } from 'react';
import { render } from 'react-dom';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { drawBuffer, VSHADER_SOURCE, FSHADER_SOURCE } from './bvf';
import { initShaders } from './shader';
import styles from './index.module.less';

const Index = forwardRef((props, ref) => {
  const { className } = props;

  useImperativeHandle(ref, () => ({
    drawArray: (array) => {
      if (array) {
        drawDance(array);
      }
    },
  }));

  const containeRef = useRef(null);
  const canRef = useRef(null);

  const onResize = useCallback(() => {
    const { offsetHeight: height, offsetWidth: width } = containeRef.current || {};

    const can = React.createElement('canvas', {
      width,
      height,
      style: { background: '#90202020' },
      ref: canRef,
    });
    render(can, containeRef.current);

    const gl = canRef.current.getContext('webgl');
    if (gl) {
      initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE);
      const aResolution = gl.getAttribLocation(gl.program, 'a_Resolution');
      gl.vertexAttrib2f(aResolution, width, height);
    }
  }, []);

  useEffect(() => {
    const ro = new ResizeObserver(onResize);
    containeRef.current && ro.observe(containeRef.current);
    return () => {
      containeRef.current && ro.unobserve(containeRef.current);
      ro.disconnect();
    };
  }, []);

  const drawDance = (data) => {
    if (canRef.current) {
      const gl = canRef.current.getContext?.('webgl');
      if (gl) {
        drawBuffer(gl, data, 'a_Position');
      }
    }
  };

  return <div ref={containeRef} className={classnames(styles.root, className)} />;
});

Index.defaultProps = {
  className: null,
};

Index.propTypes = {
  className: PropTypes.any,
};

export default Index;
